#include "dicom/handler/lookup_handler.h"

#include <boost/bind.hpp>
#include <gwbase/base/util.h>
#include <gwbase/base/logging.h>
#include <json/json.h>
#include "dicom/web_server.h"
#include "dicom/session.h"
#include "dicom/handler/handler_common.h"
#include "dicom/dmv_db.h"

namespace dicom {

static HttpHandler* CreateLookupHander(onion_request* conn) {
  return new LookupHandler(conn);
}

void LookupHandler::RegisterHandler(WebServer* s) {
  s->AddHandler("/api/folder/lookup", "GET",
                boost::bind(CreateLookupHander, _1));
}

int LookupHandler::HandleRequest(onion_request* conn, onion_response* resp) {
  Status s;
  CredentialPtr c;

  s = CheckToken(conn, &c);
  if (!s.ok()) {
    SendSimpleResponse(resp, 401, "oauth error");
    return OCS_PROCESSED;
  }

  const std::string pid = GetQueryString(conn, "pid");
  const std::string name = GetQueryString(conn, "name");
  if (pid.empty() || name.empty()) {
    LOG_WARN << "pid or name is empty";
    SendSimpleResponse(resp, 400, "pid or name is empty");
    return OCS_PROCESSED;
  }

  LOG_DEBUG << "REQUEST LOOKUP: " << pid << " : " << name;

  DmvDBPtr db = GetGateway()->dmv_mgr()->GetDB(c->email);
  FileObject fo;
  bool file_exists = db->GetSubFileByName(pid, name, &fo);

  DirObject d;
  bool dir_exists = db->GetSubDirByName(pid, name, &d);

  if (file_exists && dir_exists) {
    LOG_WARN << "child dir and file with same name";
    SendSimpleResponse(resp, 500, "child dir and file with same name");
    return OCS_PROCESSED;
  } else if (!file_exists && !dir_exists) {
    LOG_WARN << "dir/file not found: " << pid << " : " << name;
    SendSimpleResponse(resp, 404, "dir/file not found");
    return OCS_PROCESSED;
  }

  LogHippaOperation(OP_STAT_FILE, db, c, pid, name);

  Json::Value v;
  v["code"] = 0;
  v["message"] = "success";
  Json::Value item;
  if (dir_exists)
    d.ToJson(item);
  else
    fo.ToJson(item);
  v["item"] = item;
  SendJsonResult(resp, 200, v);

  if (!dir_exists) {
    LOG_DEBUG << "REQUEST LOOKUP FILE: " << pid << " : " << name << " : "
              << fo.size;
  }
  return OCS_PROCESSED;
}
}
